package com.lancoo.ccas53.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lancoo.ccas53.entity.*;
import com.lancoo.ccas53.exception.BizException;
import com.lancoo.ccas53.mapper.*;
import com.lancoo.ccas53.pojo.common.PageInfo;
import com.lancoo.ccas53.pojo.constant.ScheduleState;
import com.lancoo.ccas53.pojo.dto.TeacherDto;
import com.lancoo.ccas53.pojo.dto.TeachingClassCourseDto;
import com.lancoo.ccas53.pojo.excel.ErrorExcelVo;
import com.lancoo.ccas53.pojo.excel.ExcelTeacherInformationSettings;
import com.lancoo.ccas53.pojo.response.basicPlatform.BaseTeacher;
import com.lancoo.ccas53.pojo.vo.AllScheduleVo;
import com.lancoo.ccas53.pojo.vo.TeacherCourseInput;
import com.lancoo.ccas53.pojo.vo.TeacherCourseVo;
import com.lancoo.ccas53.pojo.vo.TeacherGroupTree;
import com.lancoo.ccas53.service.*;
import com.lancoo.ccas53.util.CollComparatorUtil;
import com.lancoo.ccas53.util.MyExcelUtils;
import com.lancoo.ccas53.util.PagingUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 教师 服务实现类
 * </p>
 *
 * @author quin.song
 * @since 2024-05-20
 */
@Service
@Slf4j
public class TeacherServiceImpl extends ServiceImpl<TeacherMapper, Teacher> implements TeacherService {

    @Resource
    private CollComparatorUtil collComparatorUtil;

    @Resource
    private YunBasicService yunBasicService;
    @Resource
    private TeacherMapper teacherMapper;
    @Resource
    private TeacherCourseService teacherCourseService;
    @Resource
    private TeachingClassTeacherMapper teachingClassTeacherMapper;
    @Resource
    private TaskInfoMapper taskInfoMapper;
    @Resource
    private RuleWeekDayMapper ruleWeekDayMapper;
    @Resource
    private PeriodSchemeService periodSchemeService;
    @Resource
    private ActiveTeachService activeTeachService;
    @Resource
    private TypeService typeService;


    @Resource
    private RoomService roomService;
    @Resource
    private CollegeService collegeService;
    @Resource
    private CollegeRoomService collegeRoomService;
    @Resource
    private MajorGradeService majorGradeService;
    @Resource
    private CssProhibitStudentMapper cssProhibitStudentMapper;
    @Resource
    private CssSelectCourseMapper cssSelectCourseMapper;
    @Resource
    private StudentMapper studentMapper;
    @Resource
    private TeachingClassMapper teachingClassMapper;
    @Resource
    private TeachingClassTeacherService teachingClassTeacherService;
    @Resource
    private TeacherCourseMapper teacherCourseMapper;
    @Resource
    private CourseApplyService courseApplyService;
    @Resource
    private CourseWeekService courseWeekService;
    @Resource
    private CampusService campusService;


    @Resource
    private CourseService courseService;
    @Resource
    private RuleUsableService ruleUsableService;
    @Resource
    private ScheduleService scheduleService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void syncBaseTeachers(Integer taskId, String schoolId) {
        List<BaseTeacher> baseTeachers = yunBasicService.getTeacher(schoolId);
        List<Teacher> syncTeacherList = new ArrayList<>();
        List<Teacher> updateTeacherList = new ArrayList<>();

        TaskInfo taskInfo = taskInfoMapper.selectOne(new LambdaQueryWrapper<TaskInfo>().eq(TaskInfo::getTaskId, taskId));
        for (BaseTeacher baseTeacher : baseTeachers) {
            syncTeacherList.add(baseTeacher.toTeacher(taskId, taskInfo.getSchoolId(), taskInfo.getTerm()));
        }
        List<Teacher> oldTeacherList = this.lambdaQuery().eq(Teacher::getTaskId, taskId).list();
        List<Teacher> addTeacher = collComparatorUtil.getAdded(oldTeacherList, syncTeacherList);
        //教师去重复 更新
        if (CollUtil.isNotEmpty(addTeacher)) {
            teacherMapper.addBatch(addTeacher);
        }
        //教师更新学院信息
        updateTeacherList = oldTeacherList.stream().filter(a -> a.getBaseCollegeId() == null).collect(Collectors.toList());
        for (Teacher item : updateTeacherList) {
            Optional<Teacher> optionalTeacher = syncTeacherList.stream().filter(a -> ObjUtil.isNotEmpty(a.getBaseCollegeId()) && ObjUtil.isNotEmpty(a.getCollegeName())
                    && a.getBaseTeacherId().equals(item.getBaseTeacherId())).findFirst();
            if (optionalTeacher.isPresent()) {
                Teacher view = optionalTeacher.get();
                item.setBaseCollegeId(view.getBaseCollegeId());
                item.setCollegeName(view.getCollegeName());
            }
        }
        this.updateBatchById(updateTeacherList);

    }


    @Override
    public PageInfo<TeacherCourseVo> getTeacherCourseList(Page page, Integer taskId, Integer campusId, String basCollegeId, Integer identity, Integer isCampusCross, String keyword, Long courseId) {
        IPage<TeacherCourseVo> result = teacherMapper.getTeacherCourse(page, taskId, campusId, basCollegeId, identity, isCampusCross, keyword, courseId);
        return PagingUtil.formatPageResult(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String copyTermSetting(Integer taskId, Integer flag) {
        switch (flag) {
            case 0:
                return this.copyRuleWeek(taskId);
            case 1:
                return this.copyActive(taskId);
            case 2:
                return this.copyRoom(taskId);
            case 3:
                return this.copyRoomSet(taskId);
            case 4:
                return this.copyTeacher(taskId);
            case 5:
                return this.copyStudent(taskId);
            case 6:
                return this.copyCourseApply(taskId);
            case 7:
                return this.copySelectCourse(taskId);
            default:
                throw new BizException("同步失败，联系管理员");
        }
    }

    @Override
    public Boolean setTeacherCourseList(TeacherCourseInput teacherCourseInput) {
        switch (teacherCourseInput.getMark()) {
            case 1:
                this.lambdaUpdate().set(Teacher::getIsCampusCross, teacherCourseInput.getIsCampusCross())
                        .in(Teacher::getTeacherId, teacherCourseInput.getTeacherIds())
                        .update();
                break;
            case 2://设置授课课程
                //清空教师课程
                teacherCourseService.lambdaUpdate()
                        .in(TeacherCourse::getTeacherId, teacherCourseInput.getTeacherIds())
                        .remove();
                teacherCourseService.saveBatch(teacherCourseInput.getTeacherCourses());
                break;
            case 3:
                //设置教师身份
                this.lambdaUpdate().set(Teacher::getIdentity, teacherCourseInput.getIdentity())
                        .in(Teacher::getTeacherId, teacherCourseInput.getTeacherIds())
                        .update();
                break;
            case 4:
                this.lambdaUpdate().set(Teacher::getCampusId, teacherCourseInput.getCampusId())
                        .set(Teacher::getCampusName, teacherCourseInput.getCampusName())
                        .in(Teacher::getTeacherId, teacherCourseInput.getTeacherIds())
                        .update();
                break;
            default:
                break;
        }
        return true;
    }

    @Override
    public Boolean clearTeacherCourseList(Integer taskId) {
        //获取教师表
        List<Teacher> teacherList = this.lambdaQuery()
                .eq(Teacher::getTaskId, taskId)
                .list();
        List<Long> teacherIds = teacherList.stream().map(Teacher::getTeacherId).collect(Collectors.toList());

//        for (Teacher teacher : teacherList){
//            teacher.setIsCampusCross(1);
//            teacher.setIdentity(null);
//            teacher.setCampusId(null);
//            teacher.setCampusName(null);
//            teacherMapper.updateById(teacher);
//        }
        teacherMapper.updateTeacherList(1, 1, null, null, taskId);

        //清空教师课程表
        teacherCourseService.lambdaUpdate()
                .eq(TeacherCourse::getTaskId, taskId)
                .in(TeacherCourse::getTeacherId, teacherIds)
                .remove();
        teacherCourseMapper.deleteTeacherByTaskId(taskId, teacherIds);
//        teacherCourseService.lambdaUpdate()
//                .eq(TeacherCourse::getTaskId,taskId)
//                .in(TeacherCourse::getTeacherId, teacherIds)
//                .remove();
        return true;
    }

    @Override
    public List<TeacherDto> getTeacherByTeachingClassIds(List<Long> teachingClassIds) {
        if (CollUtil.isEmpty(teachingClassIds)) {
            return new ArrayList<>();
        }
        List<TeacherDto> teacherList = teacherMapper.getTeacherByTeachingClassIds(teachingClassIds);
        return teacherList;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importTeacherInformationSettings(HttpServletResponse response, Integer taskId, Integer flag, MultipartFile file) {
        List<ExcelTeacherInformationSettings> excelTeachingActivities = this.readTeacherInformationSettings(file);

        if (flag == 2) {
            this.lambdaUpdate().eq(Teacher::getTaskId, taskId).set(Teacher::getIdentity, 2).update();
            teacherCourseService.lambdaUpdate().eq(TeacherCourse::getTaskId, taskId).remove();
        }


        List<Teacher> teachers = teacherMapper.selectList(new LambdaQueryWrapper<Teacher>().eq(Teacher::getTaskId, taskId));


        Map<String, Teacher> teacherMap = teacherMapper.selectList(new LambdaQueryWrapper<Teacher>().eq(Teacher::getTaskId, taskId))
                .stream().collect(Collectors.toMap(Teacher::getBaseTeacherId, Function.identity(), (o1, o2) -> o1));

        Map<String, Course> courseMap = courseService.lambdaQuery().eq(Course::getTaskId, taskId).list().stream()
                .collect(Collectors.toMap(Course::getCourseName, Function.identity(), (o1, o2) -> o1));


        Long index = 3L;
        for (ExcelTeacherInformationSettings excelTeachingActivity : excelTeachingActivities) {
            excelTeachingActivity.setId(index);
            index++;
        }


        List<ErrorExcelVo> errorExcelVos = new ArrayList<>();
        for (ExcelTeacherInformationSettings excelTeachingActivity : excelTeachingActivities) {

            if (StringUtils.isBlank(excelTeachingActivity.getBaseTeacherId()) || !teacherMap.containsKey(excelTeachingActivity.getBaseTeacherId().trim())) {
                ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                errorExcelVo.setErrorIndex(excelTeachingActivity.getId());
                errorExcelVo.setErrorMsg(excelTeachingActivity.getBaseTeacherId() + "工号教师不存在");
                errorExcelVos.add(errorExcelVo);
            }


            if (ObjUtil.isNull(excelTeachingActivity.getIdentity())) {
                ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                errorExcelVo.setErrorIndex(excelTeachingActivity.getId());
                errorExcelVo.setErrorMsg(excelTeachingActivity.getId() + "行教师身份未设置");
                errorExcelVos.add(errorExcelVo);
            }
            if (StringUtils.isBlank(excelTeachingActivity.getCourseName())) {
                continue;
            } else {
                List<String> courseIds = new ArrayList<>(Arrays.asList(excelTeachingActivity.getCourseName().split(",")));

                courseIds.forEach(o -> {
                    if (StringUtils.isBlank(o) || !courseMap.containsKey(o)) {
                        ErrorExcelVo errorExcelVo = new ErrorExcelVo();
                        errorExcelVo.setErrorIndex(excelTeachingActivity.getId());
                        errorExcelVo.setErrorMsg(o + "课程不存在");
                        errorExcelVos.add(errorExcelVo);
                    }
                });
            }
        }


        Integer errorExcelVos1 = errorExcelVos.size();
        if (CollUtil.isNotEmpty(errorExcelVos)) {
            String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"));
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel; charset=utf-8");

            MyExcelUtils.exportExcel(errorExcelVos,
                    "导入教师信息错误",
                    "错误信息",
                    ErrorExcelVo.class,
                    "导入教师信息错误" + time + ".xls", response);
            throw new BizException("教师信息导入错误");
        }

        if (errorExcelVos1 == 0) {
            List<ErrorExcelVo> errorExcelVos2 = new ArrayList<>();


            List<Teacher> teacherList1 = new ArrayList<>();


            List<TeacherCourse> teacherCourses = new ArrayList<>();

            for (ExcelTeacherInformationSettings excelTeachingActivity : excelTeachingActivities) {
                List<Teacher> teacherList = teachers.stream().filter(p -> p.getBaseTeacherId().equals(excelTeachingActivity.getBaseTeacherId())).collect(Collectors.toList());


                teacherList.forEach(t->{
                    t.setIdentity("任课教师".equals(excelTeachingActivity.getIdentity()) ? 1 : 2);
                    teacherList1.add(t);

                });

                if (StringUtils.isBlank(excelTeachingActivity.getCourseName())) {
                    continue;
                }



                if (CollUtil.isNotEmpty(teacherList)) {
                    teacherList.forEach(o -> {

                        List<Long> courseIds = teacherCourseService.lambdaQuery().eq(TeacherCourse::getTaskId, taskId)
                                .eq(TeacherCourse::getTeacherId, o.getTeacherId()).list().stream().map(TeacherCourse::getCourseId).collect(Collectors.toList());

                        List<String> coursNames = new ArrayList<>(Arrays.asList(excelTeachingActivity.getCourseName().split(",")));

                        coursNames.forEach(c -> {
                            Course course = courseMap.get(c);
                            if (!courseIds.contains(course.getCourseId())) {
                                TeacherCourse teacherCourse = new TeacherCourse();
                                teacherCourse.setTaskId(taskId);
                                teacherCourse.setTeacherId(o.getTeacherId());
                                teacherCourse.setCourseId(course.getCourseId());
                                teacherCourse.setCourseName(course.getCourseName());
                                teacherCourse.setFlag(course.getFlag());
                                teacherCourses.add(teacherCourse);
                            }
                        });
                    });
                }
            }

            Integer errorExcelVos3 = errorExcelVos2.size();

            if (CollUtil.isNotEmpty(errorExcelVos2)) {
                String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"));
                response.setCharacterEncoding("UTF-8");
                response.setHeader("content-Type", "application/vnd.ms-excel; charset=utf-8");

                MyExcelUtils.exportExcel(errorExcelVos2,
                        "导入教师信息错误",
                        "错误信息",
                        ErrorExcelVo.class,
                        "导入教师信息错误" + time + ".xls", response);
                throw new BizException("导入教学活动信息错误");
            }

            if (errorExcelVos3 == 0) {
                if (CollUtil.isNotEmpty(teacherList1)) {
                    this.saveOrUpdateBatch(teacherList1);
                }

                if (CollUtil.isNotEmpty(teacherCourses)) {
                    teacherCourseService.saveOrUpdateBatch(teacherCourses);
                }
            }
        }


    }

    @Override
    public List<Teacher> getSimpleInfo(Integer taskId) {
        return baseMapper.getSimpleInfo(taskId);
    }

    private List<ExcelTeacherInformationSettings> readTeacherInformationSettings(MultipartFile file) {
        List<ExcelTeacherInformationSettings> excelTeachingActivities = new ArrayList<>();
        List<String> expectedHeaders = Arrays.asList(
                "教师名称", "教师工号", "所属院系", "课程", "教师身份");
        try {

            InputStream inputStream = file.getResource().getInputStream();
            ExcelReader reader = ExcelUtil.getReader(inputStream, 0);
            //读取表头 判断是否符合预期
            List<String> actualHeaders = reader.readRow(1).stream()
                    .map(Object::toString).filter(org.apache.commons.lang3.StringUtils::isNotBlank)
                    .collect(Collectors.toList());
            if (!expectedHeaders.equals(actualHeaders)) {
                throw new BizException(5, "导入模板不匹配，请按照标准模板编辑后导入");
            }

            reader.addHeaderAlias("教师名称", "teacherName");
            reader.addHeaderAlias("教师工号", "baseTeacherId");
            reader.addHeaderAlias("所属院系", "collegeName");
            reader.addHeaderAlias("课程", "courseName");
            reader.addHeaderAlias("教师身份", "identity");

            excelTeachingActivities = reader.read(1, 2, ExcelTeacherInformationSettings.class);
            reader.close();
        } catch (Exception ex) {
            log.info("excel导入教学任务失败:{}", ex.getMessage());
        }

        if (excelTeachingActivities.size() == 0) {
            throw new BizException(5, "导入数据为空，请检查后重新导入");
        }

        return excelTeachingActivities;
    }

    @Override
    public List<Teacher> getTeacherByTeachingClassIdsArrange(List<Long> teachingClassIds) {
        if (CollUtil.isEmpty(teachingClassIds)) {
            return new ArrayList<>();
        }
        List<Teacher> teacherList = teachingClassTeacherMapper.getTeacherByTeachingClassIdsArrange(teachingClassIds);
        return teacherList;
    }

    @Override
    public List<TeacherGroupTree> getTeacherTree(Integer taskId, String schoolId, String term, String baseCollegeId, Integer module, String keyword) {
        List<Teacher> list = this.lambdaQuery()
                .eq(Teacher::getTaskId, taskId)
                .eq(StrUtil.isNotEmpty(baseCollegeId), Teacher::getBaseCollegeId, baseCollegeId)
                .and(StrUtil.isNotEmpty(keyword), o -> {
                    o.like(Teacher::getTeacherName, keyword)
                            .or()
                            .eq(Teacher::getBaseTeacherId, keyword);
                })
                .orderByAsc(Teacher::getTeacherName)
                .list();
        String s = UUID.randomUUID().toString();
        list.stream()
                .filter(record -> record.getGroupId() == null && record.getGroupName() == null)
                .forEach(record -> {
                    record.setGroupId(s + record.getBaseCollegeId());
                    record.setGroupName("未分组教师");
                });


        if (module == 1) {
            Page<TeachingClassCourseDto> page = new Page<>(1, -1);
            List<TeachingClassCourseDto> records = teachingClassMapper.getCourseTeachingClassForArrange(page, taskId, null).getRecords();


            List<TeachingClassTeacher> allTeachers = new ArrayList<>();
             /*
                过滤没有课的教师
                 */
            List<Long> allTeachingClassIds = records.stream()
                    .map(TeachingClassCourseDto::getTeachingClassId)
                    .distinct().collect(Collectors.toList());
            if (CollUtil.isNotEmpty(allTeachingClassIds)) {
                allTeachers = teachingClassTeacherService.lambdaQuery()
                        .in(TeachingClassTeacher::getTeachingClassId, allTeachingClassIds)
                        .list();
                List<Long> allTeacherIds = allTeachers.stream().map(TeachingClassTeacher::getTeacherId).distinct()
                        .collect(Collectors.toList());
                list = list.stream().filter(o -> allTeacherIds.contains(o.getTeacherId())).collect(Collectors.toList());
            } else {
                list = new ArrayList<>();
            }

            List<TeachingClassCourseDto> unRang = records.stream()
                    .filter(o -> o.getState() != ScheduleState.NORMAL.getCode())
                    .collect(Collectors.toList());
            RuleUsable ruleUsable = ruleUsableService.lambdaQuery()
                    .eq(RuleUsable::getTaskId, taskId)
                    .eq(RuleUsable::getCode, 6)
                    .one();
            if (ruleUsable == null) {
                throw new BizException("管理员未设置排课规则");
            }
            String rule = ruleUsable.typeToStrong();
            if (StrUtil.isNotEmpty(baseCollegeId)) {
                unRang = unRang.stream().filter(o -> o.getBaseCollegeId().equals(baseCollegeId) &&
                        ((rule.charAt(0) == '0' && o.getMajorProp() == 2 && o.getStudyNature() == 1)
                                || (rule.charAt(1) == '0' && o.getMajorProp() == 2 && o.getStudyNature() == 2)
                                || (rule.charAt(2) == '0' && o.getMajorProp() == 1 && o.getStudyNature() == 1)
                                || (rule.charAt(3) == '0' && o.getMajorProp() == 1 && o.getStudyNature() == 2))
                ).collect(Collectors.toList());
            }
//            } else {
//                unRang = unRang.stream().filter(o ->
//                        (rule.charAt(0) == '1' && o.getMajorProp() == 2 && o.getStudyNature() == 1)
//                                || (rule.charAt(1) == '1' && o.getMajorProp() == 2 && o.getStudyNature() == 2)
//                                || (rule.charAt(2) == '1' && o.getMajorProp() == 1 && o.getStudyNature() == 1)
//                                || (rule.charAt(3) == '1' && o.getMajorProp() == 1 && o.getStudyNature() == 2)
//                ).collect(Collectors.toList());
//            }
            //排课状态
            if (CollUtil.isNotEmpty(unRang)) {
                HashSet<Long> teacherIds = new HashSet<>();
                for (TeachingClassTeacher teacher : allTeachers) {
                    if (unRang.stream().anyMatch(o -> Objects.equals(o.getTeachingClassId(), teacher.getTeachingClassId())
                            && Objects.equals(o.getHourType(), teacher.getHourType()))) {
                        teacherIds.add(teacher.getTeacherId());
                    }
                }
                list.forEach(o -> {
                    if (teacherIds.contains(o.getTeacherId())) {
                        o.setScheduleState(false);
                    }
                });
            }
        }


        return Teacher.toTree(list);
    }

    @Transactional(rollbackFor = Exception.class)
    public String copyTeacher(Integer taskId) {
        TaskInfo taskInfo = taskInfoMapper.selectById(taskId);
        QueryWrapper<TaskInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("school_id", taskInfo.getSchoolId());

        String term = this.copyTerm(taskInfo.getTerm());
        term = this.copyTerm(term);
        wrapper.eq("term", term);
        List<TaskInfo> taskInfoList = taskInfoMapper.selectList(wrapper);
        if (CollUtil.isEmpty(taskInfoList) || taskInfoList.size() < 1) {
            throw new BizException("当前是系统使用的第一个学年，不存在同学期的计划，请进入后面的学年再使用该功能");
        }

        taskInfoList.remove(taskInfo);
        if (CollUtil.isNotEmpty(taskInfoList)) {
            Integer fromTaskId = taskInfoList.get(0).getTaskId();
            //获取教师表
            List<Teacher> oldTeacherList = this.lambdaQuery().eq(Teacher::getTaskId, fromTaskId).list();
            List<Teacher> newTeacherList = this.lambdaQuery().eq(Teacher::getTaskId, taskId).list();
            //保存教师表
            if (CollUtil.isNotEmpty(oldTeacherList)) {
                for (Teacher item : oldTeacherList) {
                    Optional<Teacher> optionalTeacher = newTeacherList.stream().filter(a -> a.getBaseTeacherId().equals(item.getBaseTeacherId())).findFirst();
                    if (optionalTeacher.isPresent()) {
                        Teacher teacher = optionalTeacher.get();
                        BeanUtils.copyProperties(item, teacher);
                        teacher.setTaskId(taskId);
                        this.updateById(teacher);
                    }
                }
            }
            //获取教师课程表
            List<TeacherCourse> oldTeacherCourseList = teacherCourseService.lambdaQuery().eq(TeacherCourse::getTaskId, fromTaskId).list();
            teacherCourseService.lambdaUpdate().eq(TeacherCourse::getTaskId, taskId).remove();
            //保存教师课程表
            if (CollUtil.isNotEmpty(oldTeacherCourseList)) {
                for (TeacherCourse item : oldTeacherCourseList) {
                    TeacherCourse view = new TeacherCourse();
                    view.setTaskId(taskId);
                    view.setTeacherId(item.getTeacherId());
                    view.setFlag(item.getFlag());
                    view.setCourseId(item.getCourseId());
                    view.setCourseName(item.getCourseName());
                    if (teacherCourseService.save(view)) {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        throw new BizException("同步失败");
                    }
                }
            }
        }

        return "成功";
    }

    public String copyTerm(String term) {
        if (StringUtils.isNotBlank(term)) {
            //检查最后一个字符
            char lastChar = term.charAt(term.length() - 1);
            if (lastChar == '1') {
                //第四位-1
                char fourthChar = term.charAt(3);
                char thirdChar = term.charAt(2);
                if (fourthChar == '0') {
                    //若第四位为0，则第三位减一

                    if (thirdChar == '0') {
                        //若第三位为0 ，则第二位减一
                    } else {
                        thirdChar--;
                    }
                    //将第四位设置为9
                    fourthChar = '9';
                } else {
                    fourthChar--;
                }

                //第九位减一
                char ninthChar = term.charAt(8);
                char eightChar = term.charAt(7);
                if (ninthChar == '0') {
                    //第八位减一

                    if (eightChar == '0') {
                        //若第八位为0，则第七位减一
                    } else {
                        eightChar--;
                    }
                    ninthChar = '9';
                } else {
                    ninthChar--;
                }
                lastChar = '2';

                //构建新的字符串
                StringBuilder sb = new StringBuilder(term);
                sb.setCharAt(2, thirdChar);
                sb.setCharAt(3, fourthChar);
                sb.setCharAt(7, eightChar);
                sb.setCharAt(8, ninthChar);
                sb.setCharAt(sb.length() - 1, lastChar);

                return sb.toString();
            } else if (lastChar == '2') {
                // 如果最后一个字符是 "2"，则直接将最后一个数字减1
                lastChar--;

                // 构建新的字符串
                StringBuilder sb = new StringBuilder(term);
                sb.setCharAt(sb.length() - 1, lastChar);

                return sb.toString();
            }
        }
        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    public String copyRuleWeek(Integer taskId) {
        Long count = scheduleService.lambdaQuery().eq(Schedule::getTaskId, taskId)
                .isNotNull(Schedule::getTimeCode).count();
        if (count > 0) {
            throw new BizException("已进行排课，课时方案暂不支持修改");
        }
        TaskInfo taskInfo = taskInfoMapper.selectById(taskId);
        QueryWrapper<TaskInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("school_id", taskInfo.getSchoolId());
        //20240810  修改
        String term = this.copyTerm(taskInfo.getTerm());
        term = this.copyTerm(term);

        wrapper.eq("term", term);
        List<TaskInfo> taskInfoList = taskInfoMapper.selectList(wrapper);
        if (CollUtil.isEmpty(taskInfoList) || taskInfoList.size() < 1) {
            throw new BizException("当前是系统使用的第一个学年，不存在同学期的计划，请进入后面的学年再使用该功能");
        }

        taskInfoList.remove(taskInfo);
        if (CollUtil.isNotEmpty(taskInfoList)) {
            Integer fromTaskId = taskInfoList.get(0).getTaskId();
            //获取同学期课时表
            List<RuleWeekDay> oldWeekList = ruleWeekDayMapper.selectList(new LambdaQueryWrapper<RuleWeekDay>().eq(RuleWeekDay::getTaskId, fromTaskId));
            //获取同学期节次表
            List<PeriodScheme> oldPeriodList = periodSchemeService.lambdaQuery().eq(PeriodScheme::getTaskId, fromTaskId).list();
            //保存课时表
            if (CollUtil.isNotEmpty(oldWeekList)) {
                //先删除
                ruleWeekDayMapper.delete(new LambdaUpdateWrapper<RuleWeekDay>().eq(RuleWeekDay::getTaskId, taskId));
                //保存
                for (RuleWeekDay item : oldWeekList) {
                    RuleWeekDay view = new RuleWeekDay();
                    view.setTaskId(taskId);
                    view.setBaseSchemeId(item.getBaseSchemeId());
                    view.setBaseSchemeName(item.getBaseSchemeName());
                    view.setPeriodSchemes(item.getPeriodSchemes());
                    view.setCampusId(item.getCampusId());
                    view.setCampusName(item.getCampusName());
                    view.setGradeId(item.getGradeId());
                    view.setGradeName(item.getGradeName());
                    view.setWeekDayCode(item.getWeekDayCode());
                    ruleWeekDayMapper.insert(view);
                }
            } else {
                throw new BizException("未设置，同步失败");
            }
        }

        return "成功";
    }

    @Transactional(rollbackFor = Exception.class)
    public String copyActive(Integer taskId) {
        TaskInfo taskInfo = taskInfoMapper.selectById(taskId);
        QueryWrapper<TaskInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("school_id", taskInfo.getSchoolId());

        String term = this.copyTerm(taskInfo.getTerm());
        term = this.copyTerm(term);
        wrapper.eq("term", term);
        List<TaskInfo> taskInfoList = taskInfoMapper.selectList(wrapper);
        if (CollUtil.isEmpty(taskInfoList) || taskInfoList.size() < 1) {
            throw new BizException("当前是系统使用的第一个学年，不存在同学期的计划，请进入后面的学年再使用该功能");
        }

        taskInfoList.remove(taskInfo);
        if (CollUtil.isNotEmpty(taskInfoList)) {
            Integer fromTaskId = taskInfoList.get(0).getTaskId();
            //获取同学期教学活动表
            List<ActiveTeach> activeList = activeTeachService.lambdaQuery().eq(ActiveTeach::getTaskId, fromTaskId).list();
            //保存同学期教学活动表
            if (CollUtil.isNotEmpty(activeList)) {
                //先删除
                activeTeachService.lambdaUpdate().eq(ActiveTeach::getTaskId, taskId).remove();
                //保存
                for (ActiveTeach item : activeList) {
                    ActiveTeach view = new ActiveTeach();
                    view.setTaskId(taskId);
                    view.setWeek(item.getWeek());
                    view.setTypeId(item.getTypeId());
                    view.setMajorId(item.getMajorId());
                    if (!activeTeachService.save(view)) {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        throw new BizException("同步失败");
                    }
                }
            } else {
                throw new BizException("未设置，同步失败");
            }
        }

        return "成功";
    }

    @Transactional(rollbackFor = Exception.class)
    public String copyRoom(Integer taskId) {

        TaskInfo taskInfo = taskInfoMapper.selectById(taskId);
        QueryWrapper<TaskInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("school_id", taskInfo.getSchoolId());

        String term = copyTerm(taskInfo.getTerm());
        wrapper.eq("term", term);
        List<TaskInfo> taskInfoList = taskInfoMapper.selectList(wrapper);
        if (CollUtil.isEmpty(taskInfoList) || taskInfoList.size() < 1) {
            throw new BizException("上学期不存在计划，无法进行复制");
        }

        taskInfoList.remove(taskInfo);
        if (CollUtil.isNotEmpty(taskInfoList)) {
            Integer fromTaskId = taskInfoList.get(0).getTaskId();
            List<Type> typeList = typeService.lambdaQuery().eq(Type::getTaskId, fromTaskId).eq(Type::getTypeMode, 2).list();
            List<Type> newTypeList = new ArrayList<>();
            if (CollUtil.isNotEmpty(typeList)) {
                typeService.lambdaUpdate().eq(Type::getTaskId, taskId).remove();
                for (Type item : typeList) {
                    Type view = new Type();
                    BeanUtils.copyProperties(item,view);
                    view.setTaskId(taskId);
                    view.setTypeId(null);
                    newTypeList.add(view);
                }
                typeService.saveBatch(newTypeList);
            }
            //获取同学期场地表
            List<Room> oldRoomList = roomService.lambdaQuery().eq(Room::getTaskId, fromTaskId).list();
            List<Room> newRoomList = new ArrayList<>();
            if (CollUtil.isNotEmpty(oldRoomList)) {
                //先删除
                Room room = roomService.lambdaQuery().eq(Room::getTaskId, taskId).list().get(0);
                Integer campusId = room.getCampusId();
                String campusName = room.getCampusName();
                roomService.lambdaUpdate().eq(Room::getTaskId, taskId).remove();
                //保存
                for (Room item : oldRoomList) {
                    Room view = new Room();
                    BeanUtils.copyProperties(item, view);
                    view.setTaskId(taskId);
                    view.setCampusId(campusId);
                    view.setCampusName(campusName);
                    Optional<Type> optional = newTypeList.stream().filter(a -> a.getTypeName().equals(view.getRoomTypeName())).findFirst();
                    optional.ifPresent(type -> view.setRoomType(type.getTypeId()));
                    view.setRoomId(null);
                    newRoomList.add(view);
                }
                roomService.saveBatch(newRoomList);
            } else {
                throw new BizException("未设置，同步失败");
            }
        }

        return "成功";
    }

    @Transactional(rollbackFor = Exception.class)
    public String copyRoomSet(Integer taskId) {
        TaskInfo taskInfo = taskInfoMapper.selectById(taskId);
        QueryWrapper<TaskInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("school_id", taskInfo.getSchoolId());

        String term = copyTerm(taskInfo.getTerm());
        wrapper.eq("term", term);
        List<TaskInfo> taskInfoList = taskInfoMapper.selectList(wrapper);
        if (CollUtil.isEmpty(taskInfoList) || taskInfoList.size() < 1) {
            throw new BizException("上学期不存在计划，无法进行复制");
        }

        taskInfoList.remove(taskInfo);
        if (CollUtil.isNotEmpty(taskInfoList)) {
            Integer fromTaskId = taskInfoList.get(0).getTaskId();
            //获取同学期学院表
            List<College> oldCollegeList = collegeService.lambdaQuery().eq(College::getTaskId, fromTaskId).eq(College::getRoomSet, 1).list();
            //获取学院表
            List<College> newCollegeList = collegeService.lambdaQuery().eq(College::getTaskId, taskId).list();
            //获取同学期场地分配表
            List<CollegeRoom> oldCollegeRoomList = collegeRoomService.lambdaQuery().eq(CollegeRoom::getTaskId, fromTaskId).list();
            if (CollUtil.isNotEmpty(oldCollegeList)) {
                //保存学院表数据
                for (College item : oldCollegeList) {
                    Optional<College> optional = newCollegeList.stream()
                            .filter(a -> a.getBaseCollegeId().equals(item.getBaseCollegeId()) && a.getTaskId().equals(taskId))
                            .findFirst();
                    if (optional.isPresent()) {
                        College college = optional.get();
                        college.setRoomSet(1);
                        if (!collegeService.updateById(college)) {
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                            throw new BizException("学院设置状态保存失败");

                        }
                    }
                }
            }
            if (CollUtil.isNotEmpty(oldCollegeRoomList)) {
                //先删除
                collegeRoomService.lambdaUpdate().eq(CollegeRoom::getTaskId, taskId).remove();
                //保存场地分配数据
                for (CollegeRoom item : oldCollegeRoomList) {
                    CollegeRoom view = new CollegeRoom();
                    BeanUtils.copyProperties(item, view);
                    view.setId(null);
                    view.setTaskId(taskId);
                    if (!collegeRoomService.save(view)) {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        throw new BizException("场地分配保存失败");
                    }
                }
            }
        }
        return "成功";
    }

    @Transactional(rollbackFor = Exception.class)
    public String copyStudent(Integer taskId) {

        TaskInfo taskInfo = taskInfoMapper.selectById(taskId);
        QueryWrapper<TaskInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("school_id", taskInfo.getSchoolId());

        String term = this.copyTerm(taskInfo.getTerm());
        term = this.copyTerm(term);
        wrapper.eq("term", term);
        List<TaskInfo> taskInfoList = taskInfoMapper.selectList(wrapper);
        if (CollUtil.isEmpty(taskInfoList) || taskInfoList.size() < 1) {
            throw new BizException("当前是系统使用的第一个学年，不存在同学期的计划，请进入后面的学年再使用该功能");
        }

        taskInfoList.remove(taskInfo);
        if (CollUtil.isNotEmpty(taskInfoList)) {
            Integer fromTaskId = taskInfoList.get(0).getTaskId();
            //获取同学期学生信息表
            List<MajorGrade> oldMajorGradeList = majorGradeService.lambdaQuery().eq(MajorGrade::getTaskId, fromTaskId).list();
            //获取当前学生信息表
            List<MajorGrade> newMajorGradeList = majorGradeService.lambdaQuery().eq(MajorGrade::getTaskId, taskId).list();
            if (CollUtil.isNotEmpty(oldMajorGradeList)) {
                //保存数据
                for (MajorGrade item : oldMajorGradeList) {
                    Optional<MajorGrade> optional = newMajorGradeList.stream()
                            .filter(a -> a.getGradeId().equals(item.getGradeId())
                                    && a.getBaseMajorId().equals(item.getBaseMajorId())
                                    && a.getTaskId().equals(taskId))
                            .findFirst();
                    if (optional.isPresent()) {
                        MajorGrade view = optional.get();
                        view.setIsCampusCross(item.getIsCampusCross());
                        view.setCampusId(item.getCampusId());
                        view.setCampusName(item.getCampusName());
                        if (!majorGradeService.updateById(view)) {
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                            throw new BizException("更新学生信息失败");
                        }
                    }
                }
            } else {
                throw new BizException("未设置，同步失败");
            }
        }

        return "成功";
    }

    @Transactional(rollbackFor = Exception.class)
    public String copyCourseApply(Integer taskId) {
        TaskInfo taskInfo = taskInfoMapper.selectById(taskId);
        QueryWrapper<TaskInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("school_id", taskInfo.getSchoolId());

        String term = copyTerm(taskInfo.getTerm());
        wrapper.eq("term", term);
        List<TaskInfo> taskInfoList = taskInfoMapper.selectList(wrapper);
        if (CollUtil.isEmpty(taskInfoList) || taskInfoList.size() < 1) {
            throw new BizException("上学期不存在计划，无法进行复制");
        }

        taskInfoList.remove(taskInfo);
        if (CollUtil.isNotEmpty(taskInfoList)) {
            Integer fromTaskId = taskInfoList.get(0).getTaskId();
            List<CourseApply> oldApplyList = courseApplyService.lambdaQuery().eq(CourseApply::getTaskId, fromTaskId).list();
            //先删除
            courseApplyService.lambdaUpdate().eq(CourseApply::getTaskId, taskId).remove();
            //复制数据
            for (CourseApply item : oldApplyList) {
                CourseApply view = new CourseApply();
                BeanUtils.copyProperties(item, view);
                view.setTaskId(taskId);
                view.setApplyId(null);
                courseApplyService.save(view);
            }
            List<CourseWeek> oldWeekList = courseWeekService.lambdaQuery().eq(CourseWeek::getTaskId, fromTaskId).list();
            //先删除
            courseWeekService.lambdaUpdate().eq(CourseWeek::getTaskId, taskId).remove();
            //复制数据
            for (CourseWeek item : oldWeekList) {
                CourseWeek view = new CourseWeek();
                BeanUtils.copyProperties(item, view);
                view.setTaskId(taskId);
                view.setId(null);
                courseWeekService.save(view);
            }
        }

        return "成功";
    }

    @Transactional(rollbackFor = Exception.class)
    public String copySelectCourse(Integer taskId) {
        TaskInfo taskInfo = taskInfoMapper.selectById(taskId);
        QueryWrapper<TaskInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("school_id", taskInfo.getSchoolId());

        String term = this.copyTerm(taskInfo.getTerm());
        term = this.copyTerm(term);
        wrapper.eq("term", term);
        List<TaskInfo> taskInfoList = taskInfoMapper.selectList(wrapper);
        if (CollUtil.isEmpty(taskInfoList) || taskInfoList.size() < 1) {
            throw new BizException("当前是系统使用的第一个学年，不存在同学期的计划，请进入后面的学年再使用该功能");
        }

        taskInfoList.remove(taskInfo);
        if (CollUtil.isNotEmpty(taskInfoList)) {
            Integer fromTaskId = taskInfoList.get(0).getTaskId();
            //获取同学期禁选学生
            List<CssProhibitStudent> oldProhibitStuList = cssProhibitStudentMapper.selectList(new LambdaQueryWrapper<CssProhibitStudent>().eq(CssProhibitStudent::getTaskId, fromTaskId));
            if (CollUtil.isNotEmpty(oldProhibitStuList)) {
                //先删除
                cssProhibitStudentMapper.delete(new LambdaUpdateWrapper<CssProhibitStudent>().eq(CssProhibitStudent::getTaskId, fromTaskId));
                //保存禁选学生
                for (CssProhibitStudent item : oldProhibitStuList) {
                    CssProhibitStudent view = new CssProhibitStudent();
                    BeanUtils.copyProperties(item, view);
                    view.setId(null);
                    view.setTaskId(taskId);
                    cssProhibitStudentMapper.insert(view);
                }
            }
            //获取同学期选课上限
            //按专业
            List<MajorGrade> oldMajorGradeList = majorGradeService.lambdaQuery().eq(MajorGrade::getTaskId, fromTaskId).list();
            List<MajorGrade> newMajorGradeList = majorGradeService.lambdaQuery().eq(MajorGrade::getTaskId, taskId).list();
            if (CollUtil.isNotEmpty(oldMajorGradeList)) {
                for (MajorGrade item : oldMajorGradeList) {
                    Optional<MajorGrade> optional = newMajorGradeList.stream()
                            .filter(a -> a.getGradeId().equals(item.getGradeId())
                                    && a.getBaseMajorId().equals(item.getBaseMajorId())
                                    && a.getTaskId().equals(taskId))
                            .findFirst();
                    if (optional.isPresent()) {
                        MajorGrade view = optional.get();
                        view.setCreditLimit(item.getCreditLimit());
                        view.setCourseLimit(item.getCourseLimit());
                        view.setPreCreditLimit(item.getPreCreditLimit());
                        view.setPreCourseLimit(item.getPreCourseLimit());
                        majorGradeService.updateById(view);
                    }
                }
            }
            //按学生（跨专业选课）
            List<Student> oldStuList = studentMapper.selectList(new LambdaQueryWrapper<Student>().eq(Student::getTaskId, fromTaskId));
            List<Student> newStuList = studentMapper.selectList(new LambdaQueryWrapper<Student>().eq(Student::getTaskId, taskId));
            if (CollUtil.isNotEmpty(oldStuList)) {
                for (Student item : oldStuList) {
                    Optional<Student> optional = newStuList.stream()
                            .filter(a -> a.getBaseStudentId().equals(item.getBaseStudentId())
                                    && a.getTaskId().equals(taskId))
                            .findFirst();
                    if (optional.isPresent()) {
                        Student view = optional.get();
                        view.setSelectionScope(item.getSelectionScope());
                        view.setCreditLimit(item.getCreditLimit());
                        view.setCourseLimit(item.getCourseLimit());
                        view.setPreCreditLimit(item.getPreCreditLimit());
                        view.setPreCourseLimit(item.getPreCourseLimit());
                        studentMapper.updateById(view);
                    }
                }
            }

            //获取同学期课程限制
            List<CssSelectCourse> oldSelectCourseList = cssSelectCourseMapper.selectList(new LambdaQueryWrapper<CssSelectCourse>().eq(CssSelectCourse::getTaskId, fromTaskId));
            if (CollUtil.isNotEmpty(oldSelectCourseList)) {
                //先删除
                cssSelectCourseMapper.delete(new LambdaQueryWrapper<CssSelectCourse>().eq(CssSelectCourse::getTaskId, taskId));
                for (CssSelectCourse item : oldSelectCourseList) {
                    CssSelectCourse view = new CssSelectCourse();
                    BeanUtils.copyProperties(item, view);
                    view.setId(null);
                    view.setTaskId(taskId);
                    cssSelectCourseMapper.insert(view);
                }
            }
        }
        return "成功";
    }

    @Override
    public IPage<AllScheduleVo> getAllTeacherPage(Page<AllScheduleVo> page, Integer taskId, String collegeId, String keyword) {
        return baseMapper.getAllTeacherPage(page, taskId, collegeId, keyword);
    }
}
